using System;
using System.Collections;
using MonsterLove.StateMachine;
using Platform;
using UnityEngine;
using Plugin.Tool;
using static UnityEngine.InputSystem.InputAction;
using Cysharp.Threading.Tasks;
using System.Collections.Generic;
using MyFrame.Event;

public partial class Player
{
    #region Idle
    void Idle_Enter()
    {
        ZeroVelocity();
    }
    void Idle_Update()
    {
        if (xInput != 0 && !isBusy)
        {
            fsm.ChangeState(States.Move);
        }
    }
    #endregion

    #region move

    void Move_Update()
    {
        // if (xInput != 0)
        // {
        //     // 使用Lerp函数在6帧内达到最大速度
        //     var targetSpeed = xInput * moveSpeedMax;
        //     currentSpeed = Mathf.Lerp(currentSpeed, targetSpeed, Time.deltaTime / accelerationTime);
        // }
        // else
        // {
        //     // 使用Lerp函数在3帧内停下
        //     currentSpeed = Mathf.Lerp(currentSpeed, 0, Time.deltaTime / decelerationTime);
        //     if (Mathf.Abs(currentSpeed) < 0.5f)
        //     {
        //         currentSpeed = 0;
        //     }
        // }

        SetVelocity(xInput * MoveSpeed, rb.velocity.y);
        // anim.SetFloat("currentSpeed", Mathf.Abs(currentSpeed));

        if (currentSpeed == 0)
            fsm.ChangeState(States.Idle);
    }
    #endregion

    #region AirState
    void AirState_Enter()
    {
        // rb.sharedMaterial.friction = 0;
        jumpCancel = false;
        jumpButtonPressTime = jumpButtonPressDuration;
        jumpSwitch = false;

        jumpAction.performed += OnTwoJump;
    }

    void AirState_Exit()
    {
        // rb.sharedMaterial.friction = 1;
        rb.gravityScale = gravityScale;
        jumpAction.performed -= OnTwoJump;
    }
    private void OnTwoJump(CallbackContext ctx)
    {
        if (jumpSwitch && CanTwoJump)
        {
            rb.velocity = new Vector2(rb.velocity.x, 0); // 在这里将y方向的速度设置为0
            rb.gravityScale = gravityScale;
            rb.AddForce(Vector2.up * Tool.GetJumpForce(JumpHeight, rb) * 0.8f, ForceMode2D.Impulse);
            jumpCount++;
        }
    }
    // FixedUpdate()与Unity的物理系统更新是同步 用于处理物理相关的运算
    // 或者施加缓慢向下的力
    // void AirState_FixedUpdate()
    // {
    //     // 只是从高处落下就不要进这里了
    //     if (jumpCount == 1 && jumpCancel && rb.velocity.y > 0)
    //     {
    //         Debug.Log("取消跳跃");
    //         rb.AddForce(Vector2.down * jumpCancelRate);
    //     }
    // }
    void AirState_Update()
    {
        jumpButtonPressTime -= Time.deltaTime;
        if (!HasJumpInput)
        {
            jumpSwitch = true;
            // 取消跳跃   2段跳不进入
            if (jumpButtonPressTime <= 0 && jumpCount == 1 && !jumpCancel)
            {
                jumpCancel = true;
                // 处理跳跃取消，停止角色的垂直速度（假设角色有个叫 rigidbody2D 的组件来控制物理）
                if (rb.velocity.y > 0)
                {
                    // 减少角色的上升速度来实现取消跳跃效果
                    rb.velocity = new Vector2(rb.velocity.x, rb.velocity.y * 0.5f);
                }
            }
        }

        if (rb.velocity.y > 0)
            rb.gravityScale = gravityScale;
        else
            rb.gravityScale = fallGravityScale;


        //跳跃结束才抓墙
        if (rb.velocity.y <= 0.1f && IsWallDetected() && xInput != 0 && facingDir == xInput)
        {
            fsm.ChangeState(States.WallSlide);
        }

        if (IsGroundDetected() && rb.velocity.y <= 0.1f)
        {
            if (xInput != 0) fsm.ChangeState(States.Move);
            else
                fsm.ChangeState(States.Idle);
        }

        if (xInput != 0)
        {
            SetVelocity(xInput * MoveSpeed * 0.8f, rb.velocity.y);

            // 自动上台阶    摩擦力为0就不需要了 
            // if (IsStep() && !IsWallDetected())
            // {
            //     transform.position = new Vector2(transform.position.x, transform.position.y + 0.1f);
            // }
        }


    }

    #endregion

    #region Dash
    void Dash_Enter()
    {
        dashTimer = dashDuration;

        skillMgr.UseSkill(SkillEnum.Clone, transform.position);

        fx.CreateAfterImageStart();
    }
    void Dash_Update()
    {
        if (!IsGroundDetected() && IsWallDetected()) fsm.ChangeState(States.WallSlide);

        //y=0避免 掉落
        SetVelocity(dashSpeed * dashDir, 0);

        dashTimer -= Time.deltaTime;
        if (dashTimer < 0)
        {
            fsm.ChangeState(States.Idle);
        }
    }
    void Dash_Exit()
    {
        SetVelocity(0, rb.velocity.y);//重置x轴速度
        fx.CreateAfterImageStop();
    }
    #endregion

    #region WallSlide
    void WallSlide_Enter()
    {
        jumpAction.started += OnWallJump;
    }
    void WallSlide_Exit()
    {
        jumpAction.started -= OnWallJump;
    }
    /// <summary>
    /// 蹬墙跳  一段时间禁止操作
    /// </summary>
    /// <param name="ctx"></param>
    private void OnWallJump(CallbackContext ctx)
    {
        SetVelocity(5 * -facingDir, 0);// 在这里将y方向的速度设置为0
        rb.AddForce(Vector2.up * Tool.GetJumpForce(JumpHeight, rb) * 0.8f, ForceMode2D.Impulse);
        StartCoroutine(WallJump());
        fsm.ChangeState(States.AirState);

    }
    private IEnumerator WallJump()
    {
        isLockMove = true;
        yield return new WaitForSeconds(wallJumpDuration);
        isLockMove = false;
    }
    void WallSlide_Update()
    {
        if (!IsWallDetected()) fsm.ChangeState(States.AirState);

        //是否反向
        if (xInput != 0 && facingDir != xInput)
        {
            fsm.ChangeState(States.Idle);
        }

        if (IsGroundDetected())
        {
            fsm.ChangeState(States.Idle);
        }

        if (yInput < 0)
            rb.velocity = new Vector2(0, rb.velocity.y);//玩家可以控制是否加速滑墙
        else
            rb.velocity = new Vector2(0, rb.velocity.y * .4f);
    }

    #endregion

    #region Attack
    void LightDoubleAttack_AnimationFinishTrigger()
    {
        // fsm.ChangeState(States.Idle);
        // anim.speed = 2;
    }
    void LightDoubleAttack_Enter()
    {
        PlayLightAttackSound().Forget();
        HandleAttackEnter(ref heavyDoubleAttackCombo, ref lightDoubleAttackCombo,
                          stats.lightDoubleAttackMovement, "LightDoubleAttackCombo");
    }

    void HeavyDoubleAttack_Enter()
    {
        PlayLightAttackSound().Forget();
        HandleAttackEnter(ref lightDoubleAttackCombo, ref heavyDoubleAttackCombo,
                          stats.heavyDoubleAttackMovement, "HeavyDoubleAttackCombo");
    }
    void HandleAttackEnter(ref int otherCombo, ref int currentCombo, List<Vector2> attackMovement, string animParam)
    {
        // 切换攻击模式取消另一个连击
        otherCombo = 0;

        // 超出连击窗口，重置当前连击
        if (Time.time >= lastAttackTime + comboWindow)
            currentCombo = 0;

        anim.SetInteger(animParam, currentCombo);

        // 攻击导致停止攻击的时间
        attackStopMoveTime = 0.2f;

        // 攻击位移   空中不位移
        float attackDir = xInput != 0 ? xInput : facingDir;
        if (IsGroundDetected() && attackMovement.Count > 0 && currentCombo < attackMovement.Count)
            SetVelocity(attackMovement[currentCombo].x * attackDir, attackMovement[currentCombo].y);
    }

    void LightDoubleAttack_Exit()
    {
        // anim.speed = 1;
        HandlerAttackExit(ref lightDoubleAttackCombo, ref lightDoubleAttackComboMax, "LightDoubleAttackCombo");
    }

    void HeavyDoubleAttack_Exit()
    {
        HandlerAttackExit(ref heavyDoubleAttackCombo, ref heavyDoubleAttackComboMax, "HeavyDoubleAttackCombo");
    }
    void HandlerAttackExit(ref int currentCombo, ref int attackComboMax, string animParam)
    {
        currentCombo++;
        if (currentCombo > attackComboMax)
            currentCombo = 0;
        // 设置动画参数
        anim.SetInteger(animParam, currentCombo);

        lastAttackTime = Time.time;
        SetBusy(0.1f);
    }

    void LightDoubleAttack_Update()
    {
        DelayStopMove();
    }

    void HeavyDoubleAttack_Update()
    {
        DelayStopMove();
    }

    /// <summary>
    /// 等一下才停止移动
    /// </summary>
    private void DelayStopMove()
    {
        attackStopMoveTime -= Time.deltaTime;
        if (attackStopMoveTime < 0)
        {
            ZeroVelocity();
        }
    }
    private async UniTask PlayLightAttackSound()
    {
        // 等idle过去
        // await AnimationMgr.Instance.AwaitAnimAsync(anim);

        await StarTaskWithTokenByUntil(() => attackCheckCollider.enabled);

        switch (lightDoubleAttackCombo)
        {
            case 0:
                this.Emit<SoundName>(EventEnum.PlayerSound, SoundName.NormalSwordLightAttack1);
                break;
            case 1:
                this.Emit<SoundName>(EventEnum.PlayerSound, SoundName.NormalSwordLightAttack2);
                break;
            case 2:
                this.Emit<SoundName>(EventEnum.PlayerSound, SoundName.NormalSwordLightAttack3);
                break;
        }
    }

    // 重攻击
    #endregion


    #region  反击
    // 拆分成三个状态其实更方便
    private bool cloneTag;
    private ulong counterAttacktimer;
    void CounterAttack_Enter()
    {
        ZeroVelocity();

        AnimationTool.AwaitCurrentAnimWhenEnd(anim, () =>
        {
            // 弹反失败
            if (!isCounterAttack)
                CounterBackIdle();
        });
        // counterAttacktimer = ZTimer.SetTimeout(counterAttackDuration, () => CounterBackIdle());
        isLockMove = true;
    }
    void CounterAttack_Exit()
    {
        cloneTag = false;
        isLockMove = false;
    }

    void CounterAttack_OnOpenCounter(Enemy enemy)
    {
        //还是要判断距离
        if (Vector2.Distance(transform.position, enemy.transform.position) > 2f)
            return;

        if (isCounterAttack) return;
        enemy.ChangeState(States.Stunned, true);

        //防抖，不能多次触发
        if (isCounterAttack) return;

        // 弹反成功，不会主动退出当前状态
        ZTimer.ClearTimer(counterAttacktimer);

        anim.SetTrigger("SuccessCounterAttack");

        AnimationTool.AwaitAnim(anim, () =>
        {
            // 这里等的是反击动画
            AnimationTool.AwaitAnimEnd(anim, () =>
            {
                // 没有命中直接返回idle
                if (attackCheck.isCounterAttackTrigger == false)
                {
                    CounterBackIdle();
                }
            });
        });

        isCounterAttack = true;

        // 克隆技能
        // if (!cloneTag)
        //     UseSkill(SkillEnum.Clone, new Vector3(transform.position.x + facingDir, transform.position.y, 0));
        // cloneTag = true;

    }
    public void CounterBackIdle()
    {
        anim.ResetTrigger("SuccessCounterAttack");
        isCounterAttack = false;
        ChangeState(States.Idle);
    }

    public void CounterAttack()
    {
        // tirgger要等动画开始播放才 重置为false
        anim.ResetTrigger("SuccessCounterAttack");
        anim.SetTrigger("SuccessCounterAttack");

        isCounterAttack = false;
    }
    // void CounterAttack_Update()
    // {
    //     //前方有敌人可以被反击，则触发反击动画
    //     AttackCheckFrontAll<Enemy>(enemys =>
    //     {
    //         bool canBeStunned = false;
    //         foreach (var enemy in enemys)
    //         {
    //             if (enemy.CanbeStunned())
    //             {
    //                 canBeStunned = true;
    //                 enemy.ChangeState(States.Stunned, true);
    //             }
    //         }

    //         if (canBeStunned)
    //         {
    //             // 弹反成功，不会主动退出当前状态
    //             ZTimer.ClearTimer(counterAttacktimer);

    //             anim.SetTrigger("SuccessCounterAttack");

    //             AnimationMgr.Instance.AwaitNextAnim(anim, () =>
    //             {
    //                 //如果反击 没有命中，动画结束回到idle
    //                 if (isCounterAttack == true)
    //                 {
    //                     isCounterAttack = false;
    //                     ChangeState(States.Idle);
    //                 }
    //             });

    //             isCounterAttack = true;

    //             // 克隆技能
    //             // if (!cloneTag)
    //             //     UseSkill(SkillEnum.Clone, new Vector3(transform.position.x + facingDir, transform.position.y, 0));
    //             // cloneTag = true;
    //         }
    //     });
    // }

    // void CounterAttack_AnimationFinishTrigger()
    // {
    //     ChangeState(States.Idle);
    // }

    #endregion


    #region  技能
    void AimSword_Enter()
    {
        ZeroVelocity();
    }

    void AimSword_Exit()
    {
        SetBusy(.2f);
    }

    void AimSword_Update()
    {
        FlipByMouse();
        ZeroVelocity();
    }

    void CatchSword_Enter()
    {
        CameraMgr.Instance.TriggerScreenShake(shakeCounterPower);
        FlipByMouse();
        rb.velocity = new Vector2(swordReturnForce * -facingDir, rb.velocity.y);
    }

    void CatchSword_Exit()
    {
        SetBusy(.1f);
    }
    // void CatchSword_AnimationFinishTrigger()
    // {
    // ChangeState(States.Idle);
    // }

    void Blackhole_Enter()
    {
        fsm.ClearLastState();
        anim.SetBool("Idle", true);
        SkillUsed = false;
        flyTime = flyDuration;
        rb.gravityScale = 0;
    }
    void Blackhole_Exit()
    {
        rb.gravityScale = gravityScale;
    }

    void Blackhole_Update()
    {
        flyTime -= Time.deltaTime;
        if (flyTime <= 0)
        {
            rb.velocity = new Vector2(0, -0.1f);

            if (!SkillUsed)
            {
                if (TryUseSkill(SkillEnum.Blackhole))
                    SkillUsed = true;
            }
        }
        else
        {
            rb.velocity = new Vector2(0, 5f);
        }
    }

    void Blackhole_AnimationFinishTrigger()
    {
        ChangeState(States.Idle);
    }

    #endregion



}